/* 用于实现物流追踪系统中的4g通信功能 */
#include <rtthread.h>
#include <rtdevice.h>
#include <finsh.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>  // 添加缺少的头文件

#define UART_DEVICE_NAME    "uart5"  // 串口设备名称，可根据实际情况修改

static rt_device_t uart_dev = RT_NULL;
static char uart_rx_buffer[512];  // 接收缓冲区
static rt_size_t rx_buffer_index = 0;
static rt_thread_t send_thread = RT_NULL;  // 发送线程控制块
static rt_bool_t send_thread_running = RT_FALSE;  // 发送线程运行标志
extern char lon_string[];
extern char lat_string[];

extern int up_period;//上传间隔时间 s

static void send_at_command(const char *cmd);
/* 串口接收回调函数 */
extern uint32_t sw420_intensity; // Vibration intensity (0-110)
extern rt_uint8_t temperature, temperature_x, humidity, humidity_x;
static rt_err_t uart_rx_callback(rt_device_t dev, rt_size_t size)
{
    rt_size_t read_size;
    rt_base_t level;

    // 进入临界区
    level = rt_hw_interrupt_disable();

    // 读取所有可用数据
    while ((read_size = rt_device_read(dev, 0, &uart_rx_buffer[rx_buffer_index],
                                      sizeof(uart_rx_buffer) - rx_buffer_index - 1)) > 0) {
        rx_buffer_index += read_size;
        uart_rx_buffer[rx_buffer_index] = '\0';  // 确保字符串终止

        // 检测换行符或缓冲区满，处理接收数据
        if (strchr(uart_rx_buffer, '\n') || rx_buffer_index >= sizeof(uart_rx_buffer) - 1) {
            rt_kprintf("<<< UART Received: %s", uart_rx_buffer);

            // 解析接收内容
            // 1. 检测指令成功（OK响应）
            if (strstr(uart_rx_buffer, "OK")) {
                rt_kprintf("cmd ok\n");
            }
            // 2. 解析+CREG响应
            else if (strstr(uart_rx_buffer, "+CREG:")) {
                int stat, creg;
                sscanf(uart_rx_buffer, "+CREG: %d,%d", &stat, &creg);
                rt_kprintf(" CREG: cod=%d, reg=%d\n", stat, creg);
            }
            // 3. 解析+CCLK时间响应
            else if (strstr(uart_rx_buffer, "+CCLK:")) {
                char time_buf[64];
                sscanf(uart_rx_buffer, "+CCLK: \"%[^\"]\"", time_buf);
                rt_kprintf(" timedecode: %s\n", time_buf);
            }
            // 4. 得到连接成功
            else if (strstr(uart_rx_buffer, "CONNACK")) {
                rt_kprintf(" mqtt connected \r\n");}
            // 5. 异常重启
            rx_buffer_index = 0;  // 重置缓冲区索引
        }
    }
    // 退出临界区
    rt_hw_interrupt_enable(level);
    return RT_EOK;
}

/* 发送AT指令函数 */
static void send_at_command(const char *cmd)
{
    rt_size_t write_size;

    rt_kprintf(" AT Command....", cmd);
    write_size = rt_device_write(uart_dev, 0, cmd, strlen(cmd));

    if (write_size != strlen(cmd)) {
        rt_kprintf("Error: Failed to send AT command\n");
    }
}

/* MSH命令：触发AT指令 */
static void cmd_send_at(int argc, char **argv)
{
    // 组合AT指令（添加回车换行）
    char cmd[256];
    rt_snprintf(cmd, sizeof(cmd), "AT\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(1000);

    rt_snprintf(cmd, sizeof(cmd), "AT+CREG?\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(1000);

    rt_snprintf(cmd, sizeof(cmd), "AT+CNTP?\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(1000);

    rt_snprintf(cmd, sizeof(cmd), "AT+CCLK?\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(1000);
}

/* MSH命令：查询网络注册状态 */
static void cmd_check_network(int argc, char **argv)
{
    char cmd[256];
    rt_snprintf(cmd, sizeof(cmd), "AT+CREG?\r\n");
    send_at_command(cmd);
}

/* MSH命令：查询MQTT连接状态 */
static void cmd_check_mqtt(int argc, char **argv)
{
    char cmd[256];
    rt_snprintf(cmd, sizeof(cmd), "AT+MQTTSTATU\r\n");
    send_at_command(cmd);
}

/* MSH命令：配置MQTT参数 */
static void cmd_config_mqtt(int argc, char **argv)
{
    char cmd[256];
    rt_snprintf(cmd, sizeof(cmd), "AT+MCONFIG=rjcs,uU515Ic465,version=2018-10-31&res=products%%2FuU515Ic465%%2Fdevices%%2Fgyxy&et=2088447118&method=md5&sign=AvXTr5zKPPT3n5siyV1vKg%%3D%%3D\r\n");
    send_at_command(cmd);
}

/* MSH命令：连接MQTT服务器 */
static void cmd_connect_mqtt(int argc, char **argv)
{
    char cmd[256];

    // 连接MQTT服务器
    rt_snprintf(cmd, sizeof(cmd), "AT+MIPSTART=\"mqtts.heclouds.com\",\"1883\"\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(100);

    // 建立MQTT会话(发送两次，增强可靠性)
    rt_snprintf(cmd, sizeof(cmd), "AT+MCONNECT=1,60\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(50);
    rt_snprintf(cmd, sizeof(cmd), "AT+MCONNECT=1,60\r\n");
    send_at_command(cmd);
    rt_thread_mdelay(50);
}

/* MSH命令：订阅MQTT主题 */
static void cmd_subscribe_topic(int argc, char **argv)
{
    char cmd[256];
    rt_snprintf(cmd, sizeof(cmd), "AT+MSUB=\"$sys/uU515Ic465/rjcs/thing/property/post/reply\",0\r\n");
    send_at_command(cmd);
}

/* MSH命令：发布MQTT消息 */
static void cmd_publish_message(int argc, char **argv)
{
    char cmd[512];
    // 必须要用 这个函数 如果要插入数据
    rt_thread_mdelay(10000);
    // 必须要用 这个函数 如果要插入数据
    snprintf(cmd, sizeof(cmd), "AT+MPUB=\"$sys/uU515Ic465/rjcs/thing/property/post\",0,"
            "0,\"{\\22id\\22:\\222450314406\\22,"
            "\\22params\\22:{\\22rttdata\\22:{\\22value\\22:{\\22time\\22:\\222025/07/11,15:54:01\\22,"
            "\\22temp\\22:%.1f,\\22humid\\22:%d,\\22sw420\\22:%d,\\22bat\\22:34,\\22Longit\\22:%s,"
            "\\22Latit\\22:%s}}}}\"\r\n",((float)temperature + (float)temperature_x / 10.0),humidity,sw420_intensity,lon_string,lat_string);
    send_at_command(cmd);
}

/* 发布重启命令 */
static void cmd_4grst(int argc, char **argv)
{
    char cmd[256];
    rt_snprintf(cmd, sizeof(cmd), "AT+RESET\r\n");
    send_at_command(cmd);
}


/* MSH命令：完整4G+MQTT连接流程 */
static void cmd_4gmqtt_full(int argc, char **argv)
{
    cmd_check_network(argc, argv);
    rt_thread_mdelay(1000);

    cmd_check_mqtt(argc, argv);
    rt_thread_mdelay(1000);

    cmd_config_mqtt(argc, argv);
    rt_thread_mdelay(10000);

    cmd_connect_mqtt(argc, argv);
    rt_thread_mdelay(5000);

    cmd_check_mqtt(argc, argv);
    rt_thread_mdelay(500);
    cmd_subscribe_topic(argc, argv);
    rt_thread_mdelay(500);
}

/* MSH命令：发布MQTT消息 */
static void cmd_4g_disconnect(int argc, char **argv)
{
    char cmd[256];
    // 必须要用 这个函数 如果要插入数据
    rt_snprintf(cmd, sizeof(cmd), "AT+MDISCONNECT\r\n");
    send_at_command(cmd);
}
static void send_data_thread(void *parameter)
{
    while (send_thread_running)
    {
        // 发布MQTT消息（原有发布逻辑）
        char cmd[512];
        snprintf(cmd, sizeof(cmd), "AT+MPUB=\"$sys/uU515Ic465/rjcs/thing/property/post\",0,"
                "0,\"{\\22id\\22:\\222450314406\\22,"
                "\\22params\\22:{\\22rttdata\\22:{\\22value\\22:{\\22time\\22:\\222025/07/11,15:54:01\\22,"
                "\\22temp\\22:%.1f,\\22humid\\22:%d,\\22sw420\\22:%d,\\22bat\\22:34,\\22Longit\\22:%s,"
                "\\22Latit\\22:%s}}}}\"\r\n",
                ((float)temperature + (float)temperature_x / 10.0), humidity, sw420_intensity,lon_string,lat_string);
        send_at_command(cmd);

        rt_thread_mdelay(up_period*1000);  // 发送间隔，可调整
        //发送间隔位 5000的时候 可以 没有报错
    }
}

/* MSH命令：启动数据发送线程 */
static void cmd_start_send(int argc, char **argv)
{
    if (send_thread_running)
    {
        rt_kprintf("Data send thread is already running.\n");
        return;
    }

    send_thread = rt_thread_create(
        "4g_thread",
        send_data_thread,
        RT_NULL,
        2048,
        20,  // 线程优先级
        10
    );

    if (send_thread)
    {
        send_thread_running = RT_TRUE;
        rt_thread_startup(send_thread);
        rt_kprintf("Data send thread started.\n");
    }
    else
    {
        rt_kprintf("Failed to create send thread.\n");
    }
}
/* MSH命令：关闭数据发送线程 */
static void cmd_stop_send(int argc, char **argv)
{
    if (send_thread_running)
    {
        send_thread_running = RT_FALSE;
        rt_thread_delete(send_thread);
        send_thread = RT_NULL;
        rt_kprintf("Data send thread stopped.\n");
    }
    else
    {
        rt_kprintf("Data send thread is not running.\n");
    }
}
/* 串口设备初始化 */
int uart_sample_init(void)
{
    // 查找串口设备
    uart_dev = rt_device_find(UART_DEVICE_NAME);
    if (!uart_dev) {
        rt_kprintf("Error: UART device %s not found\n", UART_DEVICE_NAME);
        return RT_ERROR;
    }

    // 打开串口设备
    rt_device_open(uart_dev, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);

    // 设置接收回调函数
    rt_device_set_rx_indicate(uart_dev, uart_rx_callback);

    rt_kprintf("UART device initialized successfully\n");
    return RT_EOK;
}

/* 注册所有MSH命令 */
MSH_CMD_EXPORT(cmd_check_network, 4gstatus);
MSH_CMD_EXPORT(cmd_check_mqtt, mqttstatus);
MSH_CMD_EXPORT(cmd_config_mqtt, mqttconfig);
MSH_CMD_EXPORT(cmd_connect_mqtt, mqttconnect);
MSH_CMD_EXPORT(cmd_subscribe_topic, mqttsub);
MSH_CMD_EXPORT(cmd_publish_message, mqttpub);
MSH_CMD_EXPORT(cmd_4gmqtt_full, 4gonline);
MSH_CMD_EXPORT(cmd_4grst, 4rst);
MSH_CMD_EXPORT(cmd_4g_disconnect, 4g disconnect);
MSH_CMD_EXPORT(cmd_send_at, send_at - Send AT command to device);
/* 注册新的MSH命令  启动4g发送线程 关闭 4g发送线程 */
MSH_CMD_EXPORT(cmd_start_send, start_send - Start data sending thread);
MSH_CMD_EXPORT(cmd_stop_send, stop_send - Stop data sending thread);
